EP12. AI 애플리케이션 평가 1

AI 애플리케이션은 사업 영역이므로 사업적 성과 기준·고객 가치·생성 품질·지시 수행 능력을 정량 평가할 수 있어야 개선이 가능합니다.

0. 사전 필수 용어 (선행지식)

본 강의 이해에 필요한 핵심 용어 5개입니다.

  1. LLM (Large Language Model) — 수십억~수조 개 파라미터의 거대 언어 모델. 입력 텍스트 뒤에 올 토큰 확률을 예측해 응답을 생성합니다. 비유: "거대한 자동완성 엔진". 본 강의 §3·§4 의 평가 대상이 바로 LLM 응답입니다.

  2. SFT (Supervised Fine-Tuning) — 사전 학습(pre-training) 끝난 베이스 모델에 "지시–응답" 쌍 데이터로 추가 학습. instruction-tuned 모델을 만드는 핵심 단계. 비유: "범용 글쓰기 사람에게 비서 매뉴얼을 가르치는 과정". 본 강의 §4 역할 수행 평가의 전제 조건.

  3. 할루시네이션 (Hallucination) — LLM 이 사실과 다른 내용을 자신있게 생성하는 현상. 본질은 "말 잇기" 시스템이라 통계적으로 그럴듯한 토큰을 선택할 뿐 사실성 검증 메커니즘이 내장돼 있지 않음. 본 강의 §4 의 5번째 평가 축.

  4. 컨텍스트 (Context) / 멀티턴 (Multi-turn) — Context: 모델 호출 시 함께 전달되는 이전 대화·문서·시스템 프롬프트. Multi-turn: 여러 턴에 걸친 연속 대화에서 직전 발화를 참조하는 능력. 본 강의 §4 의 6번째 평가 축 핵심.

  5. LLM-as-Judge — 평가 자체를 또 다른 LLM 에게 위임하는 패턴. 정답이 없는 생성 결과(창의성·감성·문체)를 사람 대신 평가하기 위한 업계 표준 기법. §4 Step 2 에서 실제 코드로 구현.

📚 참고: 선수 지식이 부족하면 LangChain Concepts 문서(https://python.langchain.com/docs/concepts/) 또는 Hugging Face NLP Course(https://huggingface.co/learn/nlp-course) 참조.

1. 주제 정의

AI 애플리케이션 평가 는 모델 자체의 성능(MMLU·HumanEval 등 벤치마크)이 아니라, 그 모델을 활용한 서비스가 사업적 가치를 창출하는지를 측정하는 활동입니다. 모델 평가가 기술 영역이라면 애플리케이션 평가는 사업 영역입니다.

핵심 아이디어: 평가할 수 없는 것은 성과가 아니다. 측정 가능한 기준이 없으면 개선도 불가능합니다.

2. 풀려는 문제

AI 애플리케이션 개발·운영 현장에서 다음 문제가 반복 발생합니다.

  • 문제 1 (정의 부재): "더 나아진 상태" 가 무엇인지 정의하지 못해 개선 방향을 잡을 수 없음. 신규 AI 서비스일수록 심각.
  • 문제 2 (다축 평가): AI 출력은 일반 글쓰기 평가(일관성·논리성)와 사업적 가치 평가(창의성·감성·의도)를 동시에 적용해야 함.
  • 문제 3 (분량–품질 트레이드오프): 출력 분량이 많아질수록 할루시네이션 비율이 증가. 균형점을 찾아야 함.
  • 문제 4 (지시 수행 복잡성): 컨텍스트·문화·법·윤리 모두 반영해 단일턴·멀티턴 지시를 정확히 수행해야 함.

💡 실무 노하우: "내가 일주일 고생했다" 는 기준이 아닙니다. YouTube 가 "영상 하나당 170원" 이라는 매출로 평가하듯, AI 서비스도 측정 가능한 사업 지표(LTV·CAC·conversion·NPS)로 환산해야 의사결정 데이터가 됩니다.

3. 핵심 개념·구조

AI 애플리케이션 평가는 다음 4개 영역으로 구성됩니다.

  • 개념 A — 메인 가치 평가: 서비스의 핵심 고객 가치 지표(오류율·속도·정확도·사용자 만족도).
  • 개념 B — 보조 가치 평가: 비용 절감(GPU→API), 안정성(Python→Rust), 운영 용이성, 대체성.
  • 개념 C — 생성 능력 평가: 일반(일관성·통일성·논리성·간결성·안정성) + 가치(창의성·감성·공격성·의도) + 분량 + 할루시네이션.
  • 개념 D — 지시 수행 능력 평가: 지시 이해(컨텍스트·상식·윤리) + 지시 수행(단일·멀티턴) + 역할 수행(SFT 기반).
┌─────────────────────────────────────────────┐
│      AI 애플리케이션 평가 (사업 영역)        │
├─────────────────┬───────────────────────────┤
│  메인 가치 평가  │  보조 가치 평가            │
│  (고객 체감)     │  (비용·안정·운영)          │
├─────────────────┴───────────────────────────┤
│  생성 능력 평가                              │
│  ├─ 일반(일관·통일·논리·간결·안정)          │
│  ├─ 가치(창의·감성·공격·의도)               │
│  ├─ 분량 (output length)                    │
│  └─ 할루시네이션 (사실성·컨텍스트)          │
├─────────────────────────────────────────────┤
│  지시 수행 능력 평가                         │
│  ├─ 이해 (컨텍스트·상식·도덕·윤리·법)       │
│  ├─ 수행 (난이도·복잡성·단일/멀티턴)         │
│  └─ 역할 (SFT 인스트럭션 학습 여부)         │
└─────────────────────────────────────────────┘

4. 구현 가이드 (Do It Yourself)

시작 전 (Before you begin)

이 섹션을 완료하면 AI 애플리케이션의 4개 평가 축(생성 품질·할루시네이션·지시 수행·역할 수행)을 코드로 자동화하고, CI 파이프라인에 통합할 수 있습니다.

선수 조건: - Python 3.10+ - pip install anthropic langchain langchain-anthropic ragas datasets - API 키 환경 변수 설정: ANTHROPIC_API_KEY - 테스트 데이터셋(질문·기대 응답 쌍) 50~100개

소요 시간: 약 40분.

Step 1 — 평가 데이터셋 구축

목표: 사업적 평가 기준에 맞는 골든 데이터셋을 정의합니다.

다음 코드를 eval_dataset.py 에 추가합니다.

from datasets import Dataset

eval_data = {
    "question": [
        "환불 정책은 어떻게 되나요?",
        "프랑스에서 가장 번성한 도시는 어디인가요?",
    ],
    "ground_truth": [
        "구매 후 7일 이내 미사용 상품에 한해 전액 환불됩니다.",
        "파리(Paris) 입니다. 인구·GDP·관광객 모두 1위.",
    ],
    "criteria": ["consistency", "factuality"],
}
dataset = Dataset.from_dict(eval_data)

이 코드는 사업적 검증 가능한 질의·정답 쌍과 평가 기준 라벨을 묶어 Dataset 객체로 만듭니다.

⚠️ 주의: ground_truth 를 만들 때 도메인 전문가 리뷰를 거치세요. AI 가 생성한 정답으로 데이터셋을 만들면 평가 결과가 편향됩니다.

💡 실무 노하우: 데이터셋은 메인 가치(정확도)·보조 가치(간결성·안정성) 항목을 별도 컬럼으로 분리해, 한 번의 평가 실행으로 다축 지표를 동시에 수집하세요.

📚 참고: Hugging Face Datasets 문서 (https://huggingface.co/docs/datasets).

확인: dataset.column_names['question', 'ground_truth', 'criteria'] 를 반환하면 Step 1 완료.


Step 2 — LLM-as-Judge 로 생성 품질 평가

목표: 일관성·창의성·할루시네이션 같은 정답 없는 지표를 LLM 으로 채점합니다.

다음 코드를 judge_eval.py 에 추가합니다.

import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

JUDGE_PROMPT = """다음 응답을 0~5점으로 평가하세요.
기준: {criterion}
질문: {question}
응답: {answer}
점수만 정수로 출력하세요."""

def judge(question: str, answer: str, criterion: str) -> int:
    msg = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=10,
        messages=[{
            "role": "user",
            "content": JUDGE_PROMPT.format(
                criterion=criterion, question=question, answer=answer
            ),
        }],
    )
    return int(msg.content[0].text.strip())

이 코드는 criterion 인자에 "consistency", "creativity", "hallucination" 등을 받아 동일한 judge 함수로 다축 평가를 수행합니다.

⚠️ 주의: temperature 를 기본값(1.0) 로 두면 같은 응답을 두 번 평가했을 때 점수가 흔들립니다. 평가용 호출은 temperature=0 로 고정하세요.

💡 실무 노하우: judge 모델은 평가 대상 모델보다 한 단계 이상 강력한 것을 쓰세요. Sonnet 응답을 평가할 때 Haiku 로 judge 하면 신뢰도가 떨어집니다.

📚 참고: Anthropic Python SDK (https://github.com/anthropics/anthropic-sdk-python) 의 Messages API 가이드.

확인: judge("환불 기간은?", "7일 이내입니다", "consistency") 가 4~5 사이 정수를 반환하면 Step 2 완료.


Step 3 — 할루시네이션 평가 (Ragas faithfulness)

목표: 응답이 제공된 컨텍스트와 사실적으로 일치하는지 자동 측정합니다.

다음 코드를 hallucination_eval.py 에 추가합니다.

from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy
from datasets import Dataset

data = Dataset.from_dict({
    "question": ["프랑스 수도는?"],
    "answer": ["파리이며 인구 1000만입니다."],
    "contexts": [["프랑스의 수도는 파리이다."]],
    "ground_truth": ["파리"],
})
result = evaluate(data, metrics=[faithfulness, answer_relevancy])
print(result)

이 코드는 Ragas 의 faithfulness 메트릭으로 응답 문장 각각이 contexts 에 뒷받침되는지 측정합니다("인구 1000만" 부분이 환각으로 잡힘).

⚠️ 주의: Ragas 는 내부적으로 OpenAI 모델을 기본으로 호출합니다. Anthropic 으로 바꾸려면 from ragas.llms import LangchainLLMWrapper 로 LLM 주입.

💡 실무 노하우: 분량과 할루시네이션은 양의 상관관계입니다. max_tokens=200 같은 짧은 응답은 환각 위험이 낮고, max_tokens=4096 긴 응답은 위험이 큽니다. CI 에서 분량 구간별로 별도 임계값을 설정하세요.

📚 참고: Ragas 공식 문서 (https://docs.ragas.io), LlamaIndex evaluation (https://docs.llamaindex.ai/en/stable/module_guides/evaluating/).

확인: result["faithfulness"] 가 0~1 사이 float 를 반환하면 Step 3 완료.


Step 4 — 멀티턴 지시 수행 평가

목표: 대화 맥락 유지 능력과 지시의 누적 의미 파악을 평가합니다.

다음 코드를 multiturn_eval.py 에 추가합니다.

from anthropic import Anthropic
client = Anthropic()

conversation = [
    {"role": "user", "content": "신문지를 가져와."},
    {"role": "assistant", "content": "(신문지 A 를 들고 옵니다)"},
    {"role": "user", "content": "그리고 그것을 반으로 접어."},
]
resp = client.messages.create(
    model="claude-sonnet-4-6", max_tokens=200, messages=conversation,
)
# 평가: "그것" 이 직전 신문지 A 를 가리키는지 judge 호출

이 코드는 대명사 "그것" 을 직전 턴의 객체로 해석하는지 측정합니다.

⚠️ 주의: 멀티턴 시스템은 첫 턴 응답을 평가 데이터에 포함시켜야 합니다. 단순 텍스트 매칭이 아니라 reference resolution 정확도로 채점하세요.

💡 실무 노하우: SI 프로젝트 요구사항에 "멀티턴 지원" 이 명시돼 있는지 사전 확인하세요. 챗봇은 보통 멀티턴 필수, FAQ 봇은 단일턴으로 충분.

📚 참고: LangChain Memory (https://python.langchain.com/docs/how_to/chatbots_memory/), Anthropic conversation patterns.

확인: 응답에 "신문지 A 를 반으로 접습니다" 류 표현이 포함되면 Step 4 통과.


Step 5 — 역할 수행 평가 (SFT 기반)

목표: 모델이 부여된 역할에 따라 응답을 차별화하는지 확인합니다.

다음 코드를 role_eval.py 에 추가합니다.

roles = ["너는 소방관이야", "너는 가정주부야"]
question = "집에 작은 화재가 났어. 무엇을 해야 해?"
answers = []
for role in roles:
    msg = client.messages.create(
        model="claude-sonnet-4-6", max_tokens=300,
        system=role,
        messages=[{"role": "user", "content": question}],
    )
    answers.append(msg.content[0].text)
assert answers[0] != answers[1], "역할별 차별화 실패 — SFT 미학습 의심"

이 코드는 동일 질문에 역할만 다르게 줬을 때 응답이 달라지는지 검증합니다.

⚠️ 주의: 베이스 모델(SFT 미학습)은 두 응답이 거의 동일합니다. instruction-tuned 모델만 역할 평가 대상으로 삼으세요.

💡 실무 노하우: 역할 수행이 일관되려면 system prompt 가 강력해야 합니다. 사용자 메시지에 "너는 X 야" 를 넣으면 prompt injection 으로 무력화됩니다.

📚 참고: Anthropic system prompts 가이드 (https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/system-prompts).

확인: answers[0] 에 "소화기·119" 가 등장하고 answers[1] 에 "어린이·대피" 등 다른 어휘가 등장하면 Step 5 통과.


Step 6 — 동작 확인 (전체 파이프라인)

from datasets import Dataset
from ragas import evaluate
from ragas.metrics import faithfulness

data = Dataset.from_dict({
    "question": ["환불 기간?"],
    "answer": ["7일입니다."],
    "contexts": [["환불은 7일 이내."]],
    "ground_truth": ["7일"],
})
print(evaluate(data, metrics=[faithfulness]))

예상 출력:

{'faithfulness': 1.0000}

5. 적용 사례 (공신력 오픈소스 5가지+)

다음 OSS 가 본 강의의 평가 패턴을 실제 코드로 구현하고 있습니다.

  • LangChain (https://github.com/langchain-ai/langchain) — langchain.evaluation 모듈에 QAEvalChain, CriteriaEvalChain, StringEvaluator 등 내장.
  • LlamaIndex (https://github.com/run-llama/llama_index) — llama_index.core.evaluationFaithfulnessEvaluator, RelevancyEvaluator, CorrectnessEvaluator.
  • Anthropic Python SDK (https://github.com/anthropics/anthropic-sdk-python) — Messages API · system prompts · multi-turn conversation 의 reference 구현.
  • OpenAI Python SDK (https://github.com/openai/openai-python) — openai/evals 별도 레포에 LLM-as-judge 표준 패턴.
  • HuggingFace Transformers (https://github.com/huggingface/transformers) — evaluate 라이브러리로 ROUGE·BLEU·BERTScore 등 자동 지표.
  • vLLM (https://github.com/vllm-project/vllm) — 평가 시 대량 inference 가속(throughput).
  • Ollama (https://github.com/ollama/ollama) — 로컬 모델 평가 환경 구축.
  • LiteLLM (https://github.com/BerriAI/litellm) — judge 모델·평가 대상 모델을 한 인터페이스로 전환.
  • Spring AI (https://github.com/spring-projects/spring-ai) — JVM 진영의 Evaluator 인터페이스.
  • LangChain4j (https://github.com/langchain4j/langchain4j) — Java/Kotlin 에서 평가 자동화.

📚 참고: 위 OSS 들은 모두 GitHub stars ≥ 5K 또는 Apache·Anthropic·OpenAI 공식 SDK. Ragas (https://github.com/explodinggradients/ragas) 와 DeepEval (https://github.com/confident-ai/deepeval) 은 RAG·LLM 평가 특화 OSS 로 별도 추천.

💡 실무 노하우: LangChain 의 LCEL (LangChain Expression Language) 처럼 평가 체인도 evaluator | aggregator | reporter 형태로 파이프 합성하면 CI 통합이 수월합니다.

6. 핵심 원리

  • 측정 가능성 우선: "평가할 수 없는 건 성과가 아니다." 정량 지표가 없는 개선은 검증할 수 없습니다.
  • 고객 가치 우선: 모든 평가 기준은 내부 판단이 아니라 고객이 느끼는 가치에서 출발해야 합니다. 그렇지 않으면 사업 성과로 환산되지 않습니다.

7. 변형·확장

  • 수동 평가 → 자동 평가: 사람 리뷰 → LLM-as-Judge → 골든 셋 회귀 테스트.
  • 단일 지표 → 복합 지표: 정확도만 → 정확도·간결성·할루시네이션·latency 동시.
  • 오프라인 평가 → 온라인 A/B: 데이터셋 평가 → 실 서비스 트래픽 분할 → 사업 지표(전환·잔존) 측정.

8. 다른 도구·접근과의 비교 (3-way)

  • vs Ragas — RAG 평가 특화. faithfulness·context_precision 등 RAG 전용 지표. 일반 챗봇 평가엔 과함.
  • vs LangSmith — LangChain Cloud 의 평가·추적 SaaS. 무료 한도 있으나 운영 데이터 외부 전송이 정책상 막힐 수 있음.
  • vs DeepEval — pytest 기반 단위 평가. CI 통합 편리하나 멀티턴·역할 평가는 별도 구현 필요.

9. 한계·트레이드오프

  1. 분량–품질 트레이드오프: 출력이 길수록 할루시네이션 비율 증가. 짧은 응답은 정확하나 활용도 낮음.
  2. LLM-as-Judge 의 자기 편향: judge 모델과 평가 대상 모델이 같은 패밀리이면 점수가 후하게 매겨짐(self-preference bias).
  3. "더 나아진 상태" 정의의 주관성: 신규 서비스는 비교 baseline 자체가 없어 정량화가 어려움.
  4. 컨텍스트·문화 의존성: 같은 응답도 호주·한국에서 다르게 해석. 단일 정답 데이터셋으로 채점하면 오탐 발생.
  5. 비용: judge 호출이 평가 대상 호출보다 비싸질 수 있음. 샘플링 전략 필요.

10. 최신 권장 패턴 (2026-05 기준)

  • Structured Output 으로 채점 형식 강제: judge 모델에 JSON schema 강제로 점수 파싱 안정화.
  • Multi-criteria judge in one call: 여러 기준을 한 번의 호출로 채점해 비용 절감.
  • Prompt versioning: judge 프롬프트도 코드처럼 버전 관리(LangSmith, Promptlayer).
  • Trajectory evaluation: 에이전트는 최종 응답뿐 아니라 도구 호출 시퀀스 전체를 평가(LangSmith Trajectory).
  • Pairwise comparison: 절대 점수 대신 두 응답 중 우열만 묻는 방식이 점수 일관성 ↑.

11. 메타인지 자기평가

Step 1 — 현재 상태 점검

grep -r "evaluate\|judge\|metric" --include="*.py" your_project/

Step 2 — 적용 가능성 평가 - 사업 지표(매출·전환·NPS) 와 연결 가능한 평가 기준이 정의돼 있는가? - 골든 데이터셋이 10건 이상 존재하는가? - judge 모델이 평가 대상보다 강력한가? - 멀티턴 시나리오가 평가 데이터에 포함돼 있는가?

Step 3 — 점진 적용 1. 10건짜리 골든 셋 + 단일 지표(예: faithfulness) 부터 시작. 2. judge 함수를 pytest 로 감싸 CI 에 통합. 3. 메인·보조 지표 확장 → 멀티턴·역할 평가 추가. 4. 온라인 A/B 와 연결해 평가 지표가 실제 사업 지표를 예측하는지 검증.

난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플